﻿package  {
	import flash.display.GradientType;
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.utils.getTimer;
	public class Tentacle extends Sprite {
		private static const PARTS:Number = 30;
		private static const PART_LENGTH:Number = 1;
		/** Positional easing */
		//private static const POS_EASING:Number = 1.2;
		//private static const POS_EASING:Number = 1.2;
		private static const POS_EASING:Number = 3;
		//private static const POS_EASING:Number = 1;
		//private static const POS_EASING:Number = 2.5;
		
		private var partLength:Number = PART_LENGTH;
		
		//public var color:uint;
		public var hue:Number;
		public var burst:Boolean = false;
		public var speed:Number;
		
		//private var inc:Number = PARTS;
		private var inc:Number = 0;
		
		private var parts:Vector.<Part> = new Vector.<Part>();
		
		public var pos:Point = new Point();
		public var angle:Number;
		
		private var threshold:int = 150;
		
		public function Tentacle(x:Number = 0, y:Number = 0) {
			for (var i:int = 0; i < PARTS; i++) {
				parts.push(new Part(x, y));
			}
		}
		public function shorten():Boolean {
			partLength -= PART_LENGTH/25;
			partLength = Math.max(0, partLength);
			return partLength <= 0;
		}
		public function update():void {
			var g:Graphics = graphics;
			g.clear();
			
			var a:Number = angle;
			var tx:Number = pos.x;
			var ty:Number = pos.y;
			
			//var tv:Number = inc%threshold == 0 ? 1 : 0;
			//var tv:Number = inc%threshold < 1 ? 2 : 0;
			//var tv:Number = (inc%threshold)/threshold;
			var tv:Number = 0;
			if (inc > threshold) {
				inc -= threshold;
				threshold = 50+Math.random()*Math.random()*200
				tv = 2;
			}
			
			var m:Matrix = new Matrix();
			m.createGradientBox(100, 100, 0, tx-50, ty-50);
			//m.createGradientBox(1000, 1000, 0, 0, 0);
			
			g.moveTo(tx, ty);
			for (var i:int = 0; i < PARTS; i++) {
				//a += (Math.random()-0.5)/50;
				a += (Math.random()-0.5)*0.01;
				
				var p:Part = parts[i] as Part;
				p.x += (tx-p.x)/POS_EASING;
				p.y += (ty-p.y)/POS_EASING;
				//p.x += ((tx+(Math.random()-0.5)/2)-p.x)/1.2;
				//p.y += ((ty+(Math.random()-0.5)/2)-p.y)/1.2;
				
				tx = p.x+Math.cos(p.a)*(partLength+p.r*0.4);
				ty = p.y+Math.sin(p.a)*(partLength+p.r*0.4);
				
				//g.lineStyle((1-i/PARTS)*5*(1+position*2), 0x000000);
				
				var thickness:Number = (1-i/PARTS)*10*partLength;
				//var thickness:Number = (1-i/PARTS)*2*partLength;
				
				//g.lineStyle(thickness, 0x000000, thickness < 1 ? thickness : 1);
				//g.lineStyle(thickness, 0x5B86F7, thickness < 1 ? thickness : 1);
				//g.lineStyle(thickness, 0x000000, 1);
				//g.lineStyle(thickness, 0x5965F9, 1);
				//g.lineStyle(thickness, 0x06129F, 1);
				//g.lineStyle(thickness);	g.lineGradientStyle(GradientType.RADIAL, [0x5763F9 ,0x06129F], [1, 0.5], [0, 255], m);
				//g.lineStyle(thickness, getRGB(0.5+i/PARTS*5-time*0.5, 0.7, 1-i*i*0.001), 1);
				//g.lineStyle(thickness, 0xFFFFFF-time*0xFF+i*10, 1);
				//g.lineStyle(thickness, 0x0000FF-((-time*5+i*0.05)*0xFF)%0xFF, 1);
				//g.lineStyle(thickness, getRGB(0.5+i/PARTS*0.2-(time*0.5)%0.1, 0.7, 1-i*i*0.001), 1);
				//g.lineStyle(thickness, getRGB(0.6-(-i*0.01+time*2)%0.1, 0.7, 1-i*i*0.001), 1);
				//g.lineStyle(thickness, getRGB(0.6-(-i*0.01+inc*0.01)%0.1, 0.7, 1-i*i*0.001), 1);
				//g.lineStyle(thickness, (inc-i)%200 == 0 ? 0xFFFF00 : 0x000000, 1);
				
				//g.lineStyle(thickness, getRGB(1/6, 1, (inc-i)%100 == 0 ? 1 : 0));
				
				
				//if ((inc-i)%threshold < 1) p.v += 1;
				
				//if ((inc+i*i*0.1)%200 < 1) p.v += 1;
				//if ((inc+i*i*i*0.005)%200 < 1) p.v += 1+i*0.1;
				//if ((inc-Math.sqrt(i)*10)%200 < 1) p.v = 3;
				//p.v *= 0.5;
				//p.v -= p.v*0.1;
				
				var pv:Number = Math.abs(1-i/(PARTS/2));
				//var pv:Number = 1-i/PARTS;
				
				
				p.v += (tv*2.1-p.v)*0.05;
				p.v -= p.v*(1.1-pv*pv*pv)*0.05;
				tv = p.v;
				
				g.lineStyle(thickness, getRGB(hue, 1, Math.max(0, Math.min(1, p.v))));
				//g.lineStyle(thickness, getRGB(1/6, 1, Math.max(0, Math.min(1, p.v))));
				//g.lineStyle(thickness, getRGB(1/6, 1, Math.max(0, Math.min(1, p.v))));
				//g.lineStyle(thickness, getRGB(1/6, 0, 1));
				//g.lineStyle(thickness, getRGB(1/6, 0, 0));
				
				
				
				//g.lineStyle(thickness, color, 1);
				
				g.lineTo(tx, ty);
				
				//p.a += angleDifference(a, p.a)/2;
				p.a += angleDifference(a, p.a)/2;
				p.a %= Math.PI*2;
				
				a = p.a;
				
				//a = angles[i] += (a-angles[i])/10;
				
				//a += Math.sin(i/PARTS*Math.PI*2);
			}
			
			//inc++;
			inc += 0.2+speed;
			//inc += burst ? 1 : 0.5;
			
			//if ((inc-PARTS)%threshold < 1) threshold = 150+Math.random()*100;
			//if ((inc-PARTS)%threshold < 1) threshold = PARTS+Math.random()*Math.random()*200;
			//if ((inc-PARTS)%threshold < 1) threshold = PARTS+Math.random()*Math.random()*(200/speed);
			//if ((inc-PARTS)%threshold < 1) threshold = PARTS+(500/(1+speed));
			
			//if (burst) inc++;
		}
		private function getRGB(ch:Number, cs:Number, cv:Number):uint {
			//ch %= 1;
			//if (ch < 0) ch += 1;
			var hi:int = int(ch*6);
			var f:Number = ch*6-hi;
			hi %= 6;
			var p:Number = cv*(1-cs);
			var q:Number = cv*(1-f*cs);
			var t:Number = cv*(1-(1-f)*cs);
			var cr:Number;
			var cg:Number;
			var cb:Number;
			switch (hi) {
				case 0: cr = cv;	cg = t;		cb = p; break;
				case 1: cr = q;		cg = cv;	cb = p; break;
				case 2: cr = p;		cg = cv;	cb = t; break;
				case 3: cr = p;		cg = q;		cb = cv; break;
				case 4: cr = t;		cg = p;		cb = cv; break;
				case 5: cr = cv;	cg = p;		cb = q; break;
			}
			return (cr*0xFF << 16) | (cg*0xFF << 8) | (cb*0xFF);
		}
		private function angleDifference(a1:Number, a2:Number):Number {
			var angle:Number = a1-a2;
			if (Math.abs(angle) > Math.PI) {
				angle = angle > 0 ? angle-Math.PI*2 : Math.PI*2+angle;
			}
			return angle;
		}
	}
}